package com.proxy;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URI;
import java.net.UnknownHostException;

import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

import com.proxy.Config.ProxyRequest;

public class ServerProxy {

	private String TAG = ServerProxy.class.getSimpleName();

	private String localServerHost;
	private ServerSocket localServerSocket;
	private int localServerPort;

	public ServerProxy() {
		localServerHost = Config.LOCAL_IP_ADDRESS;
		try {
			localServerSocket = new ServerSocket(0, 1,
					InetAddress.getByName(localServerHost));
			localServerPort = localServerSocket.getLocalPort();// 有ServerSocket自动分配端口
		} catch (UnknownHostException e) {
			Log.e(TAG, e.toString());
		} catch (IOException e) {
			Log.e(TAG, e.toString());
		}

	}

	private String orignalMediaPath;

	/**
	 * // 启动代理服务器
	 */
	public void startProxy(String mediaPath) {
		orignalMediaPath = mediaPath;
		new Thread() {
			public void run() {

				Log.v(TAG, "Proxy 线程 开始 : ");
				while (true) {
					// --------------------------------------
					// 监听MediaPlayer的请求，MediaPlayer->代理服务器
					// --------------------------------------
					Log.i(TAG, ".......开始监听MediaPlayer的请求..........");
					try {
						Socket mediaPlayerSockect = localServerSocket.accept();
						Log.i(TAG, ".......接受MediaPlayer的请求..........");

						// --------连接目标服务器---------//
						String afterRedirectMediaUrl = Utils
								.getRedirectUrl(orignalMediaPath);

						URI originalURI = URI.create(afterRedirectMediaUrl);
						String remoteHost = originalURI.getHost();
						int remotePort = originalURI.getPort();
						SocketAddress remoteAddress = new InetSocketAddress(
								remoteHost,
								(remotePort == -1 ? Config.HTTP_PORT
										: remotePort));
						Socket remoteSocket = new Socket();
						remoteSocket.connect(remoteAddress);

						// Proxy转发MediaPlayer的请求
						HttpParser httpParser = new HttpParser(remoteHost,
								remotePort, localServerHost, localServerPort);
						int readBytesLen;
						byte[] readBytesBuffer = new byte[1024];
						ProxyRequest request = null;
						while ((readBytesLen = mediaPlayerSockect
								.getInputStream().read(readBytesBuffer)) != -1) {
							byte[] headBuffer = httpParser.getRequestHeader(
									readBytesBuffer, readBytesLen);
							if (headBuffer != null) {
								request = httpParser
										.getProxyRequest(headBuffer);
								break;
							}
						}
						Log.d(TAG, "request body : " + request._body);
						remoteSocket.getOutputStream().write(
								request._body.getBytes());
						remoteSocket.getOutputStream().flush();

						String fileName = Environment
								.getExternalStorageDirectory()
								.getAbsolutePath()
								+ "/proxy/text.mp4";
						File dstFile = new File(fileName);
						File parent = dstFile.getParentFile();
						if (!parent.exists()) {
							parent.mkdirs();
						}

						if (!dstFile.exists()) {
							dstFile.createNewFile();
						}
						FileOutputStream fos = new FileOutputStream(fileName);

						// Proxy获取内容
						boolean hasGetHeader = false;
						long totalSize = 0;
						byte[] remoteReplyBuffer = new byte[1024 * 50];
						InputStream remoteInputStream = remoteSocket
								.getInputStream();
						while ((readBytesLen = remoteInputStream
								.read(remoteReplyBuffer)) != -1) {
							Log.v(TAG, "转发到mediaPlayer的请求中 readBytesLen : "
									+ readBytesLen);
							totalSize += readBytesLen;
							// 转发到mediaPlayer的请求中
							mediaPlayerSockect.getOutputStream().write(
									remoteReplyBuffer, 0, readBytesLen);
							mediaPlayerSockect.getOutputStream().flush();
							if (hasGetHeader) {
								Log.d(TAG, "has got headBuffer, 直接刷进文件 ");
								fos.write(remoteReplyBuffer, 0, readBytesLen);
								fos.flush();
							} else {
								httpParser.clearHttpBody();
								byte[] headBuffer = httpParser
										.getResponseHeader(remoteReplyBuffer,
												readBytesLen);
								if (headBuffer != null) {
									Log.i(TAG, "headBuffer size = "
											+ headBuffer.length);
									fos.write(remoteReplyBuffer,
											headBuffer.length, readBytesLen
													- headBuffer.length);
									fos.flush();
									hasGetHeader = true;
								} else {
									Log.w(TAG, "do not get headBuffer ");
								}
							}
						}
						Log.v(TAG, "转发到mediaPlayer的请求中 结束 totalSize : "
								+ totalSize);
						remoteInputStream.close();
						fos.close();
						break;
					} catch (IOException e) {
						Log.e(TAG, e.toString());
					}
				}
				Log.v(TAG, "Proxy 线程 结束 : ");
			}
		}.start();
	}

	/**
	 * 获取本地播放链接
	 * <p>
	 * 替换为本地地址，是防止直接请求服务器，我们不能够进行操作。
	 * 
	 * @param url网络URL
	 */
	public void getLocalURL(final UrlListener l) {
		new AsyncTask<String, Void, String>() {

			@Override
			protected String doInBackground(String... params) {

				// ----获取对应本地代理服务器的链接----//
				String localServerUrl = "";

				// 排除HTTP特殊,如重定向
				String afterRedirectMediaUrl = Utils
						.getRedirectUrl(orignalMediaPath);
				URI originalURI = URI.create(afterRedirectMediaUrl);
				String remoteHost = originalURI.getHost();
				int remotePort = originalURI.getPort();
				if (remotePort != -1) {// URL带Port
					localServerUrl = afterRedirectMediaUrl.replace(remoteHost
							+ ":" + remotePort, localServerHost + ":"
							+ localServerPort);
				} else {// URL不带Port
					localServerUrl = afterRedirectMediaUrl.replace(remoteHost,
							localServerHost + ":" + localServerPort);
				}

				return localServerUrl;
			}

			protected void onPostExecute(String result) {
				if (l != null) {
					l.onResult(result);
				}
			};

		}.execute(orignalMediaPath);
	}

	public interface UrlListener {
		void onResult(String path);
	}
}
